﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FlashCards.Model;
using System.Data.Objects;

namespace FlashCards.WebApp.Utils
{
    public class CategoriesUtils
    {
        public static Category GetCategory(int id)
        {
            using (var context = new FlashCardsEntities())
            {
                return context.Categories.FirstOrDefault(x => x.CategoryId == id);
            }
        }

        /// <summary>
        /// Zwraca id wszystkich kategorii pod kategorią o danym id - wielopoziomowo
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static List<int> GetAllChildCategories(int id)
        {
            using (var context = new FlashCardsEntities())
            {
                var items = context.Common_Flashcards_GetCategoriesTree(id).ToList();
                var returnedList = new List<int>();

                foreach (var item in items)
                    if (item.HasValue)
                        returnedList.Add(item.Value);

                return returnedList;
            }
        }

        public static List<Category> GetAllCategories()
        {
            using (var context = new FlashCardsEntities())
            {
                return context.Categories.ToList();
            }
        }

        public static List<Category> GetCategories(int? categoryId)
        {
            using (var context = new FlashCardsEntities())
            {
                var query = context.Categories.Where(x => x.ParentCategoryId == null);
                
                foreach(var item in query)
                    GetInnerCategories(item, categoryId);

                var categories = query.ToList();
                return categories;
            }
        }

        public static void GetInnerCategories(Category category)
        {
            GetInnerCategories(category, null);
        }

        static void GetInnerCategories(Category category, int? parentId)
        {
            if (!category.ChildrenCategories.IsLoaded)
                category.ChildrenCategories.Load();


            if (!parentId.HasValue)
                foreach (var item in category.ChildrenCategories)
                    GetInnerCategories(item);
            else
            {
                if (parentId.Value == category.CategoryId)
                {
                    foreach (var item in category.ChildrenCategories)
                        GetInnerCategories(item, parentId);
                }
            }
        }


        /// <summary>
        /// Zwraca wszystkie kategorie, które są dzieckiem kategorii o parentId
        /// + wszystkie kategorie wyżej w drzewie
        /// </summary>
        /// <param name="parentId"></param>
        /// <returns></returns>
        //public static List<Category> GetCategories(int? parentId)
        //{
        //    var categories = GetAllCategories();
        //    var childCategories = categories.Where(x => x.ParentCategoryId == parentId).ToList();

        //}

        public static void AddCategory(string name)
        {
            AddCategory(name, null);
        }

        public static void AddCategory(string name, int? parentId)
        {
            using (var context = new FlashCardsEntities())
            {
                var category = new Category()
                {
                    Name = name,
                    ParentCategoryId = parentId
                };
                context.Categories.AddObject(category);
                context.SaveChanges();
            }
        }

        public static void DeleteCategory(int id)
        {
            using (var context = new FlashCardsEntities())
            {
                var category = context.Categories.FirstOrDefault(x => x.CategoryId == id);
                var childCategories = GetAllChildCategories(id, context);

                foreach (var item in childCategories)
                    context.Categories.DeleteObject(item);

                context.Categories.DeleteObject(category);
                context.SaveChanges();
            }
        }

        static List<Category> GetAllChildCategories(int id, FlashCardsEntities context)
        {
            var list = GetChildCategories(id, context);
            var toAddList = new List<Category>();
            if (list.Count > 0)
            {
                foreach (var item in list)
                {
                    var newList = GetChildCategories(item.CategoryId, context);
                    toAddList.AddRange(newList);
                }
            }

            list.AddRange(toAddList);

            return list;
        }

        static List<Category> GetChildCategories(int id, FlashCardsEntities context)
        {
            return context.Categories.Where(x => x.ParentCategoryId == id).ToList();
        }

    }
}